package com.hucsmn.chatroom;

import java.io.*;

/**
 * 输入输出流复制工具类。
 */
public class StreamCopy {
    /**
     * 默认缓冲区大小。
     */
    public static final int BUFFER_SIZE = 8192;

    /**
     * 分配默认大小的缓冲区来复制数据流。
     *
     * @param in 输入流。
     * @param out 输出流。
     * @return 总字节数。
     * @throws IOException 数据流读写异常。
     */
    public static long copy(InputStream in, OutputStream out) throws IOException {
        return copy(in, out, new byte[BUFFER_SIZE]);
    }

    /**
     * 使用指定的缓冲区来复制数据流。
     *
     * @param in 输入流。
     * @param out 输出流。
     * @param buf 缓冲区。
     * @return 总字节数。
     * @throws IOException 数据流读写异常。
     */
    public static long copy(InputStream in, OutputStream out, byte[] buf) throws IOException {
        if (in == null || out == null || buf == null) {
            throw new NullPointerException();
        }
        if (buf.length <= 0) {
            throw new IllegalArgumentException();
        }

        long total = 0;
        int n = 0;
        while ((n = fillBuffer(in, buf)) >= 0) {
            out.write(buf, 0, n);
            total += n;
        }
        out.flush();
        return total;
    }

    /**
     * 尽可能地将更多的输入数据填充进缓冲区。
     *
     * @param in 输入流。
     * @param buf 缓冲区。
     * @return 缓冲区填入的字节数，遇到文件末尾并且没有读取到任何数据时，返回 -1。
     * @throws IOException 数据读取异常。
     */
    private static int fillBuffer(InputStream in, byte[] buf) throws IOException {
        int count = 0;
        while (count < buf.length) {
            int n = in.read(buf, count, buf.length - count);
            if (n < 0) {
                break;
            }
            count += n;
        }
        return count != 0 ? count : -1;
    }
}
